import { Select } from "ol/interaction";
import Draw, {
    createBox,
    createRegularPolygon,
} from "ol/interaction/Draw";
import { Fill, Stroke, Style, Text, Circle } from "ol/style";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import Overlay from 'ol/Overlay';
import LineString from 'ol/geom/LineString';
import Point from 'ol/geom/Point';
import Polygon from 'ol/geom/Polygon';
import CirclePolygon from 'ol/geom/Circle';
import { getArea, getLength } from 'ol/sphere'
import { unByKey } from 'ol/Observable';
import { formartLonLat, decimalKeep } from "@/utils"
function Interaction(map) {
    this.map = map;
    this.draw = null;
    this.drawLayer = null
    this.geometryFunction - null// 更新几何坐标时调用的函数。
    this.measureTooltipElement = null //tooltip里面的div
    this.measureTooltip = null //提示tooltip
    this.geometryCollection = []
    this.overlayCollection = []
}

/**
 * description 捕获点击地图的要素
 * @param Layer 容纳要素的图层
 */
Interaction.prototype.addSelect = function (Layers) {
    let selet = new Select({ layers: Layers })
    this.map.addInteraction(selet)
    return selet
}

Interaction.prototype.initDraw = function (layerName, yjtype) {
    //------------添加绘制图层
    let drawVectorLayer = new VectorLayer({
        source: new VectorSource(),
        zIndex: 20,
    });
    drawVectorLayer.set("layerName", layerName);
    this.map.addLayer(drawVectorLayer);
    this.drawLayer = drawVectorLayer
}
//手动绘制预警区
Interaction.prototype.addYjDraw = function (featureType, yjtype) {
    if (featureType == "Polygon") {
        let geometryFunction
        if (!this.drawLayer) {
            this.initDraw("绘制图层")
            this.draw = new Draw({
                source: this.drawLayer.getSource(),
                type: featureType,
                geometryFunction: geometryFunction,
                freehand: true,//这个是手绘模式
                //绘制时，在地图上呈现的样式
                style: new Style({
                    fill: new Fill({
                        color: "rgba(255, 255, 255, 0.2)",
                    }),
                    stroke: new Stroke({
                        color: "#ffcc33",
                        width: 2,
                    }),
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: "#ffcc33",
                        }),
                    }),
                }),
            })
        }
        if (yjtype == "3") {
            this.draw = new Draw({
                source: this.drawLayer.getSource(),
                type: featureType,
                geometryFunction: geometryFunction,
                freehand: true,//这个是手绘模式
                //绘制时，在地图上呈现的样式
                style: new Style({
                    fill: new Fill({
                        color: "rgba(255, 255, 255, 0.2)",
                    }),
                    stroke: new Stroke({
                        color: "#e23e30",
                        width: 2,
                    }),
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: "#e23e30",
                        }),
                    }),
                }),
            });
        } else if (yjtype == "2") {
            this.draw = new Draw({
                source: this.drawLayer.getSource(),
                type: featureType,
                geometryFunction: geometryFunction,
                freehand: true,//这个是手绘模式
                //绘制时，在地图上呈现的样式
                style: new Style({
                    fill: new Fill({
                        color: "rgba(255, 255, 255, 0.2)",
                    }),
                    stroke: new Stroke({
                        color: "#de8615",
                        width: 2,
                    }),
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: "#de8615",
                        }),
                    }),
                }),
            });
        } else if (yjtype == "1") {
            this.draw = new Draw({
                source: this.drawLayer.getSource(),
                type: featureType,
                geometryFunction: geometryFunction,
                freehand: true,//这个是手绘模式
                //绘制时，在地图上呈现的样式
                style: new Style({
                    fill: new Fill({
                        color: "rgba(255, 255, 255, 0.2)",
                    }),
                    stroke: new Stroke({
                        color: "#FFFD03",
                        width: 2,
                    }),
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: "#FFFD03",
                        }),
                    }),
                }),
            });
        } else if (yjtype == "0") {
            this.draw = new Draw({
                source: this.drawLayer.getSource(),
                type: featureType,
                geometryFunction: geometryFunction,
                freehand: true,//这个是手绘模式
                //绘制时，在地图上呈现的样式
                style: new Style({
                    fill: new Fill({
                        color: "rgba(255, 255, 255, 0.2)",
                    }),
                    stroke: new Stroke({
                        color: "#327eef",
                        width: 2,
                    }),
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: "#327eef",
                        }),
                    }),
                }),
            });
        }
        this.cancelDraw()
        this.map.addInteraction(this.draw);
        let listener;
        this.createMeasureTooltip()
        let sketch
        let _this = this;
        this.draw.on("drawstart", function (e) {
            sketch = e.feature; //绘制的要素
            let tooltipCoord = e.coordinate;// 绘制的坐标
            listener = sketch.getGeometry().on('change', function (evt) {
                let geom = e.feature.getGeometry();//绘制的几何要素
                tooltipCoord = geom.getInteriorPoint().getCoordinates();//坐标
            })
        })
        this.draw.on("drawend", function (e) {
            let geom = e.feature.getGeometry();//绘制的几何要素
            if (yjtype == "3") {
                e.feature.setStyle(() => {
                    return new Style({
                        fill: new Fill({
                            color: "#e23e30",
                        }),
                    })
                })
            }else if(yjtype == "2"){
                e.feature.setStyle(() => {
                    return new Style({
                        fill: new Fill({
                            color: "#de8615",
                        }),
                    })
                })
            }else if(yjtype == "1"){
                e.feature.setStyle(() => {
                    return new Style({
                        fill: new Fill({
                            color: "#FFFD03",
                        }),
                    })
                })
            }else if(yjtype == "0"){
                e.feature.setStyle(() => {
                    return new Style({
                        fill: new Fill({
                            color: "#327eef",
                        }),
                    })
                })
            }
            unByKey(listener);
            _this.geometryCollection.push(geom)//添加几何体
            // _this.cancelDraw(); //移除上一次绘制事件
            sketch = null; //置空当前绘制的要素对象
            // console.log(_this.geometryCollection, "geom")
        })
    }
}
Interaction.prototype.cancelYjDraw = function () {
    this.cancelDraw(); //移除交互
    this.clearPolygon(); //清除图层上的所有要素
    this.geometryCollection = []
    this.cancelDraw(); //移除上一次绘制事件
    this.draw = null;
}
Interaction.prototype.cleargeometryCollection = function () {
    this.geometryCollection = []
}
//mode 0 多绘制模式
//mode 1 单绘制模式，只能保留一个几何体
Interaction.prototype.addDraw = function (featureType, mode = 0) {
    //如果是单绘制事件，之前的多边形要删除
    if (mode == 1) {
        this.clearPolygon(); //清除图层上的所有要素
        this.geometryCollection = [] //清除geom
    }
    let geometryFunction
    if (!this.drawLayer) {
        this.initDraw("绘制图层")
        this.draw = new Draw({
            source: this.drawLayer.getSource(),
            type: featureType,
            geometryFunction: geometryFunction,
            // freehand: true,//这个是手绘模式
            //绘制时，在地图上呈现的样式
            style: new Style({
                fill: new Fill({
                    color: "rgba(255, 255, 255, 0.2)",
                }),
                stroke: new Stroke({
                    color: "#ffcc33",
                    width: 2,
                }),
                image: new Circle({
                    radius: 7,
                    fill: new Fill({
                        color: "#ffcc33",
                    }),
                }),
            }),
        });
    }
    //先清除之前的draw
    this.cancelDraw()
    //
    if (featureType == "Rectangle") {
        featureType = 'Circle'
        geometryFunction = createBox()
    }
    if (featureType == "Square") {
        featureType = 'Circle'
        geometryFunction = createRegularPolygon(4)
    }
    this.draw = new Draw({
        source: this.drawLayer.getSource(),
        type: featureType,
        geometryFunction: geometryFunction,
        // freehand: true,//这个是手绘模式
        //绘制时，在地图上呈现的样式
        style: new Style({
            fill: new Fill({
                color: "rgba(255, 255, 255, 0.2)",
            }),
            stroke: new Stroke({
                color: "#ffcc33",
                width: 2,
            }),
            image: new Circle({
                radius: 7,
                fill: new Fill({
                    color: "#ffcc33",
                }),
            }),
        }),
    });
    this.map.addInteraction(this.draw);
    //先创建一个测量提示框
    this.createMeasureTooltip()
    let listener;
    let sketch
    let _this = this;
    //当绘制开始
    this.draw.on("drawstart", function (e) {
        sketch = e.feature; //绘制的要素
        let tooltipCoord = e.coordinate;// 绘制的坐标
        //绑定change事件，根据绘制几何类型得到测量长度值或面积值，并将其设置到测量工具提示框中显示
        listener = sketch.getGeometry().on('change', function (evt) {
            let geom = evt.target;//绘制几何要素
            let output;
            if (geom instanceof Polygon) {
                output = _this.formatArea(geom);//面积值
                tooltipCoord = geom.getInteriorPoint().getCoordinates();//坐标
            } else if (geom instanceof LineString) {
                output = _this.formatLength(geom);//长度值
                tooltipCoord = geom.getLastCoordinate();//坐标
            } else if (geom instanceof CirclePolygon) {
                output = _this.formatCircle(geom);//半径与圆心与面积
                tooltipCoord = geom.getCenter();//坐标
            }
            _this.measureTooltipElement.innerHTML = output;//将测量值设置到测量工具提示框中显示
            _this.measureTooltip.setPosition(tooltipCoord);//设置测量工具提示框的显示位置
        });
    });
    //当绘制完成
    this.draw.on("drawend", function (e) {
        console.log("e:", e);

        // console.log(" e:", e);
        // console.log(" e.feature:", e.feature);
        // console.log(" e.feature.getGeometry():", e.feature.getGeometry());

        let drawpoint = e.feature.getGeometry().getCoordinates();
        console.log(
            " e:",
            drawpoint
        );
        if (featureType == "Point") {
            window.functionForpoints(drawpoint)
        }

        // window.functionDrawpoint(drawpoint)
        let geom = e.feature.getGeometry();//绘制的几何要素
        // console.log(geom.getCoordinates(), "geom.getCoordinates()");
        if (geom instanceof Point) {
            //绘制点时，drawstart不会触发，所以在drawend中进行测量经纬度
            _this.measureTooltipElement.innerHTML = _this.formatCoor(geom);//将测量值设置到测量工具提示框中显示
            _this.measureTooltip.setPosition(geom.getLastCoordinate());//设置测量工具提示框的显示位置
        }

        _this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-static'; //设置测量提示框的样式
        let closebtn = document.createElement('span');
        closebtn.className = 'ol-measure-clear';
        closebtn.innerHTML = '×';
        closebtn.onclick = function () {
            _this.drawLayer.getSource().removeFeature(e.feature);
            closebtn.parentNode.parentNode.remove();

            let coors = e.feature.getGeometry().getCoordinates()[0]
            let res = []
            coors.forEach(item => {
                console.log(item);
                res.push({ longitude: item[0], latitude: item[1] })
            })
            console.log(JSON.stringify(res), "res");
        };
        _this.measureTooltipElement.appendChild(closebtn);
        _this.measureTooltip.setOffset([0, -7]);
        // unset sketch
        sketch = null; //置空当前绘制的要素对象
        _this.measureTooltipElement = null; //置空测量工具提示框对象
        _this.createMeasureTooltip();//重新创建一个测试工具提示框显示结果
        unByKey(listener);
        // if (geom instanceof Point) {
        //     //如果是绘制点，就不清除绘制事件
        //     return
        // }
        _this.geometryCollection.push(geom)//添加几何体
        _this.cancelDraw(); //移除上一次绘制事件
        _this.draw = null;

    });

}

//清除绘制，包括绘制的几何图形
Interaction.prototype.clearDraw = function () {
    this.draw && this.cancelDraw(); //移除交互
    this.clearPolygon(); //清除图层上的所有要素
    this.geometryCollection = []
}

//清除图层上的所有要素
Interaction.prototype.clearPolygon = function () {
    this.drawLayer && this.drawLayer.getSource().clear(); //清除图层上的所有要素
    // console.log(this.overlayCollection, "this.overlayCollection");
    this.overlayCollection.forEach(item => {
        this.map.removeOverlay(item)
    })
}

//撤销
Interaction.prototype.removeLastPoint = function () {
    this.draw && this.draw.removeLastPoint()
}

//取消
Interaction.prototype.cancelDraw = function () {
    this.map.removeInteraction(this.draw);
}

Interaction.prototype.getGeometryCollection = function () {
    return this.geometryCollection
}

/**
 *创建一个新的测量工具提示框（tooltip）
 */
Interaction.prototype.createMeasureTooltip = function () {
    if (this.measureTooltipElement) {
        this.measureTooltipElement.parentNode.removeChild(this.measureTooltipElement);
    }
    this.measureTooltipElement = document.createElement('div');
    this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
    this.measureTooltip = new Overlay({
        element: this.measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center'
    });
    this.measureTooltip.type = "绘制overlay"
    this.map.addOverlay(this.measureTooltip);
    this.overlayCollection.push(this.measureTooltip)
}

/**
 * 测量长度输出
 * @param {ol.geom.LineString} line
 * @return {string}
 */
Interaction.prototype.formatLength = function (line) {
    let sourceProj = this.map.getView().getProjection();//获取投影坐标系
    let length = getLength(line, { projection: sourceProj });
    let output;
    if (length > 100) {
        output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km';
    } else {
        output = (Math.round(length * 100) / 100) + ' ' + 'm';
    }
    return output;
}

/**
 * 测量面积输出,如果是矩形，就测量长宽
 * @param {ol.geom.Polygon} polygon
 * @return {string}
 */
Interaction.prototype.formatArea = function (polygon) {
    let sourceProj = this.map.getView().getProjection();//获取投影坐标系
    let area = getArea(polygon, { projection: sourceProj });
    let output;
    if (area > 10000) {
        output = (Math.round(area / 1000000 * 100) / 100) +
            ' ' + 'km<sup>2</sup>';
    } else {
        output = (Math.round(area * 100) / 100) +
            ' ' + 'm<sup>2</sup>';
    }
    return output;
}

/**
 * 测量面积半径圆心输出
 * @param {ol.geom.Polygon} polygon
 * @return {string}
 */
Interaction.prototype.formatCircle = function (polygon) {
    let sourceProj = this.map.getView().getProjection();//获取投影坐标系
    let centerLogLat = formartLonLat(polygon.getCenter(), 2)
    let radius = decimalKeep(polygon.getRadius() * (sourceProj.getMetersPerUnit()), 2);
    let area = decimalKeep(Math.PI * Math.pow(radius, 2), 2);
    let outputArea;
    if (area > 10000) {
        outputArea = (Math.round(area / 1000000 * 100) / 100) +
            ' ' + 'km<sup>2</sup>';
    } else {
        outputArea = (Math.round(area * 100) / 100) +
            ' ' + 'm<sup>2</sup>';
    }
    if (radius > 1000) {
        radius = (Math.round(radius / 1000 * 100) / 100) +
            ' ' + 'km<sup>2</sup>';
    } else {
        radius = (Math.round(radius * 100) / 100) +
            ' ' + 'm<sup>2</sup>';
    }
    let output = `
    <div>圆心:${centerLogLat[0]},${centerLogLat[1]}</div>
    <div>半径:${radius}</div>
    <div>面积:${outputArea}</div>
    `
    return output;
}

/**
 * 判断是否是矩形，并且判断是否是方形
 * @param {ol.geom.Polygon} polygon
 * @return {string}
 */
Interaction.prototype.polygonType = function (polygon) {
    let coors = polygon.getCoordinates()[0]
    function isRectangle(coors) {
        //如果有五个坐标，并且第一个坐标与最后一个坐标相等
        if (coors && coors.length == 5 && (coors[0][0] == coors[coors.length - 1][0] && coors[0][1] == coors[coors.length - 1][1])) {
            if (coors[0][1] == coors[1][1] && coors[1][0] == coors[2][0] && coors[2][1] == coors[3][1] && coors[3][0] == coors[4][0]) {
                return true
            } else {
                return false
            }
        } else {
            return false
        }
    }
    //已经通过矩形判断的情况下,长等于宽
    function isSquare(coors) {
        let c = coors[0][0] - coors[1][0]
        let k = coors[1][1] - coors[2][1]
        if (c == k) {
            return true
        } else {
            return false
        }
    }
    //判断是否是多边形
    if (polygon && polygon instanceof Polygon) {
        //判断是否是矩形
        if (isRectangle(coors)) {
            //判断是否是方形
            if (isSquare(coors)) {
                return "square";
            } else {
                return "rectangle"
            }
        } else {
            return "polygon"
        }
    } else {
        return "none"
    }
}

/**
 * 测量坐标值输出
 * @param {ol.geom.Polygon} polygon
 * @return {string}
 */
Interaction.prototype.formatCoor = function (point) {
    let output;
    let coor = point.getCoordinates()
    if (coor) {
        let lonlat = formartLonLat(coor, 2)
        output = `<div>经度:${lonlat[0]}</div><div>纬度:${lonlat[1]}</div>`
    }
    return output;
}

export default Interaction